package cn.xxstudy.permission.help

import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.fragment.app.FragmentActivity
import cn.xxstudy.permission.help.callback.PermissionResultCallback
import cn.xxstudy.permission.help.task.PermissionTask
import cn.xxstudy.permission.help.view.PermissionDialog

/**
 * @author ：wuxinxi on 2020/11/10 .
 * @packages ：cn.xxstudy.permission.help .
 * TODO:权限处理类
 */
class PermissionBuilder(val activity: FragmentActivity, val permissions: Array<out String>) {
    companion object {
        private const val FRAGMENT_TAG = "PERMISSION_FRAGMENT"
    }

    /**
     * 已授权的权限列表
     */
    val grantedPermissions = mutableListOf<String>()

    /**
     * 拒绝的权限列表
     */
    val deniedPermissions = mutableListOf<String>()

    /**
     * 永久拒绝权限列表
     */
    val permanentDeniedPermissions = mutableListOf<String>()

    var permissionResultCallback: PermissionResultCallback? = null

    lateinit var permissionResultListener: (
        allGranted: Boolean,
        grantedPermissions: Array<String>,
        deniedPermissions: Array<String>,
        permanentDeniedPermissions: Array<String>
    ) -> Unit


    /**
     * 被永久拒绝的是否去设置页手动授权
     */
    var permanentDeniedPermissionToSettings = false
    var permanentDeniedPermissionRequestState = RequestState.NONE

    /**
     * 被拒绝的是否去设置页手动授权
     */
    var deniedPermissionRetry = false
    var deniedPermissionRequestState = RequestState.NONE

    private val permissionTask = PermissionTask(this)

    /**
     * 添加权限拒绝后重新申请
     */
    fun addDeniedPermissionCallbackRetry(): PermissionBuilder {
        this.deniedPermissionRetry = true
        return this
    }

    /**
     * 添加全局被勾选了不再提示授权 前往设置页授权
     */
    fun addPermanentDeniedPermissionToSettings(): PermissionBuilder {
        this.permanentDeniedPermissionToSettings = true
        return this
    }

    fun request(permissionResultCallback: PermissionResultCallback) {
        this.permissionResultCallback = permissionResultCallback
        permissionTask.request()
    }

    fun request(
        permissionResultListener: (
            allGranted: Boolean,
            grantedPermissions: Array<String>,
            deniedPermissions: Array<String>,
            permanentDeniedPermissions: Array<String>
        ) -> Unit
    ) {
        this.permissionResultListener = permissionResultListener
        permissionTask.request()
    }

    fun resultCallbackIsInitialized(): Boolean {
        return this::permissionResultListener.isInitialized
    }

    fun getPermissionFragment(): PermissionFragment {
        val fragmentManager = activity.supportFragmentManager
        val permissionFragment = fragmentManager.findFragmentByTag(FRAGMENT_TAG)
        if (permissionFragment != null) {
            return permissionFragment as PermissionFragment
        }
        val fragment = PermissionFragment()
        fragmentManager.beginTransaction().add(fragment, FRAGMENT_TAG).commitNow()
        return fragment
    }

    fun jumpSettings() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        val uri = Uri.fromParts("package", activity.packageName, null)
        intent.data = uri
        getPermissionFragment().startActivityForResult(intent, PermissionFragment.REQUEST_SETTINGS_CODE)
    }

    fun retryAgain() {
        showDialog(deniedPermissions.toTypedArray(), "重新授权", "以下权限被拒绝请重新授权", {
            permissionTask.retryRequest()
        }, {
            deniedPermissionRequestState = RequestState.REQUESTED
        })
    }

    fun showPermanentDeniedPermissionsDialog() {
        showDialog(permanentDeniedPermissions.toTypedArray(), "重新授权", "以下权限被拒绝请前往设置页重新授权", {
            permissionTask.requestSettings()
        }, {
            this.permanentDeniedPermissionRequestState = RequestState.REQUESTED
        })
    }


    private fun showDialog(
        permissions: Array<String>,
        title: String,
        content: String,
        positive: () -> Unit,
        negative: () -> Unit
    ) {
        PermissionDialog.show(
            activity,
            permissions,
            title,
            content,
            {
                positive()
            },
            {
                negative()
                callback(
                    deniedPermissions.size == 0 && permanentDeniedPermissions.size == 0,
                    grantedPermissions.toTypedArray(),
                    deniedPermissions.toTypedArray(),
                    permanentDeniedPermissions.toTypedArray()
                )
            }
        )
    }

    fun callback(
        allGranted: Boolean,
        grantedPermissions: Array<String>,
        deniedPermissions: Array<String>,
        permanentDeniedPermissions: Array<String>
    ) {
        this.permissionResultCallback?.callback(
            allGranted,
            grantedPermissions,
            deniedPermissions,
            permanentDeniedPermissions
        )

        if (resultCallbackIsInitialized()) {
            this.permissionResultListener.invoke(
                allGranted,
                grantedPermissions,
                deniedPermissions,
                permanentDeniedPermissions
            )
        }
    }
}